package com.rzgeo.rzmaplib.comp;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.Spinner;

import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.data.Feature;
import com.esri.arcgisruntime.data.FeatureTable;
import com.esri.arcgisruntime.layers.FeatureLayer;
import com.rzgeo.rzmaplib.R;
import com.rzgeo.rzmaplib.comp.RmlTaskList.TaskStruct;
import com.rzgeo.rzmaplib.util.RmlDataUtil;
import com.rzgeo.rzmaplib.util.RmlUtil;
import com.rzgeo.rzmaplib.util.RmlUtil.Dict;

import java.io.File;
import java.util.ArrayList;
import java.util.Map;

public class RmlTaskEditor extends FrameLayout {
    private ArrayList<Code> _codes = null;
    private FeatureLayer _featureLayer;
    private Feature _taskFeauture;
    private OnResult _onResult;

    public interface OnResult {
        void onOK(Feature feature);

        void onReset(Feature feature);

        void onDelete(Feature feature);

        void onCancel();

        void onTakePhoto(Feature taskFeature, File photoStrogeFile, RmlPhotosViewer.OnTakePhotoResult onResult);

        void onViewPhotos(Feature taskFeature,RmlPhotosViewer.OnResult onResult);
    }

    private EditText _tin_code;
    private EditText _tin_area;
    private Spinner _sp_state;
    private Spinner _tin_code_1;
    private Spinner _tin_code_2;
    private Spinner _tin_code_3;
    private Spinner _tin_code_4;
    private EditText _tin_remark;
    //    private Spinner[] _extCodeInput;
    private Button _btn_reset;
    private Button _btn_delete;
    private Button _btn_viewp_photos;
    private Button _btn_take_photo;
    private Button _btn_cancel;
    private Button _btn_ok;

    public RmlTaskEditor(Context context) {
        super(context);
        initUI(context);
    }

    public RmlTaskEditor(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initUI(context);
    }

    public RmlTaskEditor(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initUI(context);
    }

    private void initUI(Context context) {
        View subView = LayoutInflater.from(context).inflate(R.layout.comp_task_editor, null);
        subView.setLayoutParams(
                new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        this.addView(subView);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        _sp_state = findViewById(R.id.sp_state);
        _tin_code = findViewById(R.id.tin_code);

        _tin_area = findViewById(R.id.tin_area);

        _tin_code_1 = findViewById(R.id.tin_code_1);
        _tin_code_2 = findViewById(R.id.tin_code_2);
        _tin_code_3 = findViewById(R.id.tin_code_3);
        _tin_code_4 = findViewById(R.id.tin_code_4);

        _tin_code_1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                String code = (String) _tin_code_1.getAdapter().getItem(position);
                loadSubSpinner(code,null);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        _tin_remark = findViewById(R.id.tin_remark);

        _btn_reset = findViewById(R.id.btn_reset);
        _btn_delete = findViewById(R.id.btn_delete);
        _btn_viewp_photos = findViewById(R.id.btn_viewp_hotos);
        _btn_take_photo = findViewById(R.id.btn_take_photo);
        _btn_cancel = findViewById(R.id.btn_cancel);
        _btn_ok = findViewById(R.id.btn_ok);

        _btn_reset.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if(_taskFeauture==null)
                    return;

                FeatureTable ft = _featureLayer.getFeatureTable();
                if(!ft.canUpdate(_taskFeauture)){
                    RmlUtil.Tip.Toast("要素不可编辑");
                }else{
                    Map<String, Object> attr = _taskFeauture.getAttributes();

                    attr.put(TaskStruct.FnSTATE,TaskStruct.State1NotSurvey);
                    attr.put(TaskStruct.FnCODE1,null);
                    attr.put(TaskStruct.FnCODE3,null);
                    attr.put(TaskStruct.FnCODE3,null);
                    attr.put(TaskStruct.FnCODE4,null);
                    attr.put(TaskStruct.FnEXLABEL1,null);
                    attr.put(TaskStruct.FnEXLABEL2,null);
                    attr.put(TaskStruct.FnEXLABEL3,null);
                    attr.put(TaskStruct.FnEXLABEL4,null);
                    attr.put(TaskStruct.FnREMARK,null);

                    final ListenableFuture<Void> fu = ft.updateFeatureAsync(_taskFeauture);
                    fu.addDoneListener(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                fu.get();

                                loaddata();

                                _onResult.onReset(_taskFeauture);

                                RmlUtil.Tip.Toast("重置数据");
                            } catch (Exception e) {
                                RmlUtil.Log.Err(e);
                            }
                        }
                    });

                }
            }
        });
        _btn_delete.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if(_taskFeauture==null)
                    return;
                FeatureTable ft = _featureLayer.getFeatureTable();
                if(!ft.canDelete(_taskFeauture)){
                    RmlUtil.Tip.Toast("要素不可删除");
                }else{
                    final ListenableFuture<Void> df = ft.deleteFeatureAsync(_taskFeauture);
                    df.addDoneListener(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                df.get();
                                _onResult.onDelete(_taskFeauture);
                                _taskFeauture=null;
                                loaddata();
                            } catch (Exception e) {
                                RmlUtil.Log.Err(e);
                            }
                        }
                    });
                }
            }
        });
        _btn_viewp_photos.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
            _onResult.onViewPhotos(_taskFeauture, new RmlPhotosViewer.OnResult() {
                @Override
                public void onDelete(Feature feature) {

                }

                @Override
                public void onCancel() {

                }
            } );
            }
        });
        _btn_take_photo.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                _onResult.onTakePhoto(_taskFeauture, null, new RmlPhotosViewer.OnTakePhotoResult() {
                    @Override
                    public void onResult(File file) {

                    }

                    @Override
                    public void onCancel() {

                    }
                });
            }
        });
        _btn_cancel.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                _onResult.onCancel();
            }
        });
        _btn_ok.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if(_taskFeauture==null)
                    return;

                FeatureTable ft = _featureLayer.getFeatureTable();
                if(!ft.canUpdate(_taskFeauture)){
                    RmlUtil.Tip.Toast("要素不可编辑");
                }

                Map<String, Object> attr = _taskFeauture.getAttributes();

                attr.put(TaskStruct.FnSTATE,TaskStruct.getStates()[_sp_state.getSelectedItemPosition()]);

                String[] codeslv1 = getNames(1, null);
                String code1 = codeslv1[_tin_code_1.getSelectedItemPosition()];
                attr.put(TaskStruct.FnCODE1,code1);

                attr.put(TaskStruct.FnCODE2,
                        getNames(2, code1)[_tin_code_2.getSelectedItemPosition()]);

                String[] codeslv3 = getNames(3, code1);
                if (codeslv3 != null) {
                    attr.put(TaskStruct.FnCODE3,
                            codeslv3[_tin_code_3.getSelectedItemPosition()]);
                }

                String[] codeslv4 = getNames(4, code1);
                if (codeslv3 != null) {
                    attr.put(TaskStruct.FnCODE4,
                            codeslv4[_tin_code_4.getSelectedItemPosition()]);
                }

                attr.put(TaskStruct.FnREMARK,_tin_remark.getText().toString());

                final ListenableFuture<Void> uf = ft.updateFeatureAsync(_taskFeauture);
                uf.addDoneListener(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            uf.get();
                            _onResult.onOK(_taskFeauture);
                        } catch (Exception e) {
                            RmlUtil.Log.Err(e);
                        }
                    }
                });

                _onResult.onOK(_taskFeauture);
            }
        });
    }

    public void setup(FeatureLayer taskFeatureLayer, Feature taskFeauture,@NonNull OnResult onResult) {
        _featureLayer=taskFeatureLayer;
        _taskFeauture=taskFeauture;
        _onResult=onResult;
        loaddata();
    }

    private void loaddata() {
        if(_taskFeauture==null){

            setSpinner(_sp_state, null,null);
            setSpinner(_tin_code_1, null,null);
            setSpinner(_tin_code_2, null,null);
            setSpinner(_tin_code_3, null,null);
            setSpinner(_tin_code_4, null,null);
            _tin_remark.setText("");
        }else{
            Map<String, Object> attr = _taskFeauture.getAttributes();

            setSpinner(_sp_state, TaskStruct.getStates(),
                    Dict.getString(attr, TaskStruct.FnSTATE));

            String code1 = Dict.getString(attr, TaskStruct.FnCODE1);
            _tin_code.setText(code1);

            String[] codeslv1 = getNames(1, null);
            setSpinner(_tin_code_1, codeslv1, code1);

            loadSubSpinner(code1,attr);

            _tin_remark.setText(Dict.getString(attr, TaskStruct.FnREMARK));
        }
    }

    private void loadSubSpinner(String code1, Map<String, Object> attr) {
        if(attr==null){
            String[] code2s = getNames(2, code1);
            if(code2s!=null)
                setSpinner(_tin_code_2, code2s,code2s[0]);
            else
                setSpinner(_tin_code_2, code2s,null);
        }
        else
            setSpinner(_tin_code_2, getNames(2, code1),
                    Dict.getString(attr, TaskStruct.FnCODE2));

        String[] codeslv3 = getNames(3, code1);
        if (codeslv3 != null) {
            if(attr==null)
                setSpinner(_tin_code_3, codeslv3,codeslv3[0]);
            else
                setSpinner(_tin_code_3, codeslv3,
                        Dict.getString(attr, TaskStruct.FnCODE3));
            _tin_code_3.setVisibility(VISIBLE);
        } else
            _tin_code_3.setVisibility(GONE);

        String[] codeslv4 = getNames(4, code1);
        if (codeslv3 != null) {
            if(attr==null)
                setSpinner(_tin_code_4, codeslv4,codeslv4[0]);
            else
                setSpinner(_tin_code_4, codeslv4,
                        Dict.getString(attr, TaskStruct.FnCODE4));
            _tin_code_4.setVisibility(VISIBLE);
        } else
            _tin_code_4.setVisibility(GONE);
    }

    private class Code {
        public Code(String name, String code, int lv, String code1) {
            this.name = name;
            Code = code;
            Lv = lv;
            Code1 = code1;
        }

        String name;
        String Code;
        int Lv;
        String Code1;
    }

    private String[] getNames(int lv, String superName) {
        if (_codes == null) {
            _codes = new ArrayList<>();

            RmlDataUtil.Csv csv = RmlDataUtil.Csv.readFromAsset(getContext(), "配置/编码表.csv");
            for (int i = 1; i < csv.getRowNum(); i++) {

                String row = csv.getRow(i);
                String[] rows = row.split(",");
                Code code;
                if(rows.length<3){
                    RmlUtil.Log.Err("发现空行");
                    continue;
                }
                else if(rows.length<4)
                    code= new Code(
                        rows[1],
                        rows[0],
                        RmlUtil.Convert.Int(rows[2]),
                            null);
                else
                    code= new Code(
                            rows[1],
                            rows[0],
                            RmlUtil.Convert.Int(rows[2]),
                            rows[3]);
                _codes.add(code);
            }
        }

        String superCode = null;
        if(superName!=null){
            for (Code code:
                    _codes) {
                if(superName.equalsIgnoreCase(code.name)){
                    superCode=code.Code;
                    break;
                }
            }
        }


        ArrayList<String> codes = new ArrayList<>();
        if (superCode != null && lv > 1) {
            for (Code c : _codes
                    ) {
                if (c.Lv == lv && superCode.equalsIgnoreCase(c.Code1))
                    codes.add(c.name);
            }
        } else {
            for (Code c : _codes
                    ) {
                if (c.Lv == lv)
                    codes.add(c.name);
            }
        }

        if(codes.size()==0)
            return null;
        return codes.toArray(new String[0]);
    }

    private void setSpinner(Spinner spinner, String[] datas, String current) {
        if(datas==null||current==null){
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                    getContext(),
                    android.R.layout.simple_spinner_item,
                    new String[0]);
            spinner.setAdapter(adapter);
        }else{
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                    getContext(),
                    android.R.layout.simple_spinner_item,
                    datas);
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            int defaultSel = 0;
            for (int i = 0; i < datas.length; i++) {
                if (current.equalsIgnoreCase(datas[i])) {
                    defaultSel=i;
                }
            }
            spinner.setAdapter(adapter);
            spinner.setSelection(defaultSel);
        }
    }
}
